package com.hgb.mall.admin.services.impl;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.hgb.mall.admin.dao.*;
import com.hgb.mall.admin.dto.PmsProductParam;
import com.hgb.mall.admin.dto.PmsProductQueryParam;
import com.hgb.mall.admin.dto.PmsProductResult;
import com.hgb.mall.admin.services.PmsProductService;
import com.hgb.mall.mbg.entity.PmsProduct;
import com.hgb.mall.mbg.entity.PmsProductVertifyRecord;
import com.hgb.mall.mbg.entity.PmsSkuStock;
import com.hgb.mall.mbg.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static org.mybatis.dynamic.sql.SqlBuilder.*;

/**
 * 商品管理Service实现类
 * Created by hgb on 2020/4/26.
 */
@Service
public class PmsProductServiceImpl implements PmsProductService {
    private static final Logger LOGGER = LoggerFactory.getLogger(PmsProductServiceImpl.class);
    @Autowired
    private PmsProductMapper productMapper;
    @Autowired
    private PmsMemberPriceDao memberPriceDao;
    @Autowired
    private PmsMemberPriceMapper memberPriceMapper;
    @Autowired
    private PmsProductLadderDao productLadderDao;
    @Autowired
    private PmsProductLadderMapper productLadderMapper;
    @Autowired
    private PmsProductFullReductionDao productFullReductionDao;
    @Autowired
    private PmsProductFullReductionMapper productFullReductionMapper;
    @Autowired
    private PmsSkuStockDao skuStockDao;
    @Autowired
    private PmsSkuStockMapper skuStockMapper;
    @Autowired
    private PmsProductAttributeValueDao productAttributeValueDao;
    @Autowired
    private PmsProductAttributeValueMapper productAttributeValueMapper;
    @Autowired
    private CmsSubjectProductRelationDao subjectProductRelationDao;
    @Autowired
    private CmsSubjectProductRelationMapper subjectProductRelationMapper;
    @Autowired
    private CmsPreferenceAreaProductRelationDao preferenceAreaProductRelationDao;
    @Autowired
    private CmsPreferenceAreaProductRelationMapper preferenceAreaProductRelationMapper;
    @Autowired
    private PmsProductDao productDao;
    @Autowired
    private PmsProductVertifyRecordDao productVertifyRecordDao;

    @Override
    public int create(PmsProductParam productParam) {
        int count;
        //创建商品
        PmsProduct product = new PmsProduct();
        BeanUtils.copyProperties(productParam, product);
        product.setId(null);
        productMapper.insertSelective(product);
        //根据促销类型设置价格：会员价格、阶梯价格、满减价格
        Long productId = product.getId();
        //会员价格
        relateAndInsertList(memberPriceDao, productParam.getMemberPriceList(), productId);
        //阶梯价格
        relateAndInsertList(productLadderDao, productParam.getProductLadderList(), productId);
        //满减价格
        relateAndInsertList(productFullReductionDao, productParam.getProductFullReductionList(), productId);
        //处理sku的编码
        handleSkuStockCode(productParam.getSkuStockList(), productId);
        //添加sku库存信息
        relateAndInsertList(skuStockDao, productParam.getSkuStockList(), productId);
        //添加商品参数,添加自定义商品规格
        relateAndInsertList(productAttributeValueDao, productParam.getProductAttributeValueList(), productId);
        //关联专题
        relateAndInsertList(subjectProductRelationDao, productParam.getSubjectProductRelationList(), productId);
        //关联优选
        relateAndInsertList(preferenceAreaProductRelationDao, productParam
                .getPreferenceAreaProductRelationList(), productId);
        count = 1;
        return count;
    }

    private void handleSkuStockCode(List<PmsSkuStock> skuStockList, Long productId) {
        if (CollectionUtils.isEmpty(skuStockList))
            return;
        for (int i = 0; i < skuStockList.size(); i++) {
            PmsSkuStock skuStock = skuStockList.get(i);
            if (StringUtils.isEmpty(skuStock.getSkuCode())) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                //日期
                String skuCode = sdf.format(new Date()) +
                        //四位商品id
                        String.format("%04d", productId) +
                        //三位索引id
                        String.format("%03d", i + 1);
                skuStock.setSkuCode(skuCode);
            }
        }
    }

    @Override
    public PmsProductResult getUpdateInfo(Long id) {
        return productDao.getUpdateInfo(id);
    }

    @Override
    public int update(Long id, PmsProductParam productParam) {
        int count;
        //更新商品信息
        PmsProduct product = productParam;
        product.setId(id);
        productMapper.updateByPrimaryKeySelective(product);
        //会员价格
        memberPriceMapper.delete(c -> c.where(PmsMemberPriceDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(memberPriceDao, productParam.getMemberPriceList(), id);
        //阶梯价格

        productLadderMapper.delete(c -> c.where(PmsProductLadderDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(productLadderDao, productParam.getProductLadderList(), id);
        //满减价格
        productFullReductionMapper
                .delete(c -> c.where(PmsProductFullReductionDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(productFullReductionDao, productParam.getProductFullReductionList(), id);
        //修改sku库存信息
        handleUpdateSkuStockList(id, productParam);
        //修改商品参数,添加自定义商品规格

        productAttributeValueMapper
                .delete(c -> c.where(PmsProductAttributeValueDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(productAttributeValueDao, productParam.getProductAttributeValueList(), id);
        //关联专题
        subjectProductRelationMapper
                .delete(c -> c.where(CmsSubjectProductRelationDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(subjectProductRelationDao, productParam.getSubjectProductRelationList(), id);
        //关联优选
        preferenceAreaProductRelationMapper.delete(
                c -> c.where(CmsPreferenceAreaProductRelationDynamicSqlSupport.productId, isEqualTo(id)));
        relateAndInsertList(preferenceAreaProductRelationDao, productParam.getPreferenceAreaProductRelationList(), id);
        count = 1;
        return count;
    }

    private void handleUpdateSkuStockList(Long id, PmsProductParam productParam) {
        //当前的sku信息
        List<PmsSkuStock> currSkuList = productParam.getSkuStockList();
        //当前没有sku直接删除
        if (CollUtil.isEmpty(currSkuList)) {
            skuStockMapper.delete(c -> c.where(PmsSkuStockDynamicSqlSupport.productId, isEqualTo(id)));
            return;
        }
        //获取初始sku信息
        List<PmsSkuStock> oriStuList = skuStockMapper
                .select(c -> c.where(PmsSkuStockDynamicSqlSupport.productId, isEqualTo(id)));
        //获取新增sku信息
        List<PmsSkuStock> insertSkuList = currSkuList.stream().filter(item -> item.getId() == null)
                                                     .collect(Collectors.toList());
        //获取需要更新的sku信息
        List<PmsSkuStock> updateSkuList = currSkuList.stream().filter(item -> item.getId() != null)
                                                     .collect(Collectors.toList());
        List<Long> updateSkuIds = updateSkuList.stream().map(PmsSkuStock::getId).collect(Collectors.toList());
        //获取需要删除的sku信息
        List<PmsSkuStock> removeSkuList = oriStuList.stream().filter(item -> !updateSkuIds.contains(item.getId()))
                                                    .collect(Collectors.toList());
        handleSkuStockCode(insertSkuList, id);
        handleSkuStockCode(updateSkuList, id);
        //新增sku
        if (CollUtil.isNotEmpty(insertSkuList)) {
            relateAndInsertList(skuStockDao, insertSkuList, id);
        }
        //删除sku
        if (CollUtil.isNotEmpty(removeSkuList)) {
            List<Long> removeSkuIds = removeSkuList.stream().map(PmsSkuStock::getId).collect(Collectors.toList());
            skuStockMapper.delete(c -> c.where(PmsSkuStockDynamicSqlSupport.id, isIn(removeSkuIds)));
        }
        //修改sku
        if (CollUtil.isNotEmpty(updateSkuList)) {
            for (PmsSkuStock pmsSkuStock : updateSkuList) {
                skuStockMapper.updateByPrimaryKeySelective(pmsSkuStock);
            }
        }

    }

    @Override
    public List<PmsProduct> list(PmsProductQueryParam productQueryParam, Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        return productMapper.select(c -> c.where(PmsProductDynamicSqlSupport.deleteStatus, isEqualTo(0))
                                          .and(PmsProductDynamicSqlSupport.publishStatus, isEqualToWhenPresent(productQueryParam
                                                  .getPublishStatus()))
                                          .and(PmsProductDynamicSqlSupport.verifyStatus, isEqualToWhenPresent(productQueryParam
                                                  .getVerifyStatus()))
                                          .and(PmsProductDynamicSqlSupport.name, isLikeWhenPresent(productQueryParam
                                                  .getKeyword()).then(s -> "%" + s + "%"))
                                          .and(PmsProductDynamicSqlSupport.productSn, isEqualToWhenPresent(productQueryParam
                                                  .getProductSn()))
                                          .and(PmsProductDynamicSqlSupport.brandId, isEqualToWhenPresent(productQueryParam
                                                  .getBrandId()))
                                          .and(PmsProductDynamicSqlSupport.productCategoryId, isEqualToWhenPresent(productQueryParam
                                                  .getProductCategoryId()))
                                          .orderBy(PmsProductDynamicSqlSupport.id.descending())
        );
    }

    @Override
    public int updateVerifyStatus(List<Long> ids, Integer verifyStatus, String detail) {

        List<PmsProductVertifyRecord> list = new ArrayList<>();
        int count = productMapper.update(c -> c.set(PmsProductDynamicSqlSupport.verifyStatus).equalTo(verifyStatus)
                                               .where(PmsProductDynamicSqlSupport.id, isIn(ids)));

        //修改完审核状态后插入审核记录
        for (Long id : ids) {
            PmsProductVertifyRecord record = new PmsProductVertifyRecord();
            record.setProductId(id);
            record.setCreateTime(new Date());
            record.setDetail(detail);
            record.setStatus(verifyStatus);
            record.setVertifyMan("test");
            list.add(record);
        }
        productVertifyRecordDao.insertList(list);
        return count;
    }

    @Override
    public int updatePublishStatus(List<Long> ids, Integer publishStatus) {
        return productMapper.update(c -> c.set(PmsProductDynamicSqlSupport.publishStatus).equalTo(publishStatus)
                                          .where(PmsProductDynamicSqlSupport.id, isIn(ids)));
    }

    @Override
    public int updateRecommendStatus(List<Long> ids, Integer recommendStatus) {
        return productMapper.update(c -> c.set(PmsProductDynamicSqlSupport.recommandStatus).equalTo(recommendStatus)
                                          .where(PmsProductDynamicSqlSupport.id, isIn(ids)));
    }

    @Override
    public int updateNewStatus(List<Long> ids, Integer newStatus) {
        return productMapper.update(c -> c.set(PmsProductDynamicSqlSupport.newStatus).equalTo(newStatus)
                                          .where(PmsProductDynamicSqlSupport.id, isIn(ids)));
    }

    @Override
    public int updateDeleteStatus(List<Long> ids, Integer deleteStatus) {
        return productMapper.update(c -> c.set(PmsProductDynamicSqlSupport.deleteStatus).equalTo(deleteStatus)
                                          .where(PmsProductDynamicSqlSupport.id, isIn(ids)));
    }

    @Override
    public List<PmsProduct> list(String keyword) {
        return productMapper.select(c -> c.where(PmsProductDynamicSqlSupport.deleteStatus, isEqualTo(0))
                                          .and(PmsProductDynamicSqlSupport.name, isLikeWhenPresent(keyword)
                                                  .then(s -> "%" + s + "%"))
                                          .or(PmsProductDynamicSqlSupport.productSn, isLikeWhenPresent(keyword)
                                                  .then(s -> "%" + s + "%"))
                                          .and(PmsProductDynamicSqlSupport.deleteStatus, isEqualTo(0))
        );
    }

    /**
     * 建立和插入关系表操作
     *
     * @param dao       可以操作的dao
     * @param dataList  要插入的数据
     * @param productId 建立关系的id
     */
    private void relateAndInsertList(Object dao, List dataList, Long productId) {
        try {
            if (CollectionUtils.isEmpty(dataList)) return;
            for (Object item : dataList) {
                Method setId = item.getClass().getMethod("setId", Long.class);
                setId.invoke(item, (Long) null);
                Method setProductId = item.getClass().getMethod("setProductId", Long.class);
                setProductId.invoke(item, productId);
            }
            Method insertList = dao.getClass().getMethod("insertList", List.class);
            insertList.invoke(dao, dataList);
        } catch (Exception e) {
            LOGGER.warn("创建产品出错:{}", e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }

}
